package org.lds.simple.disruptor.strategy;

import lombok.extern.slf4j.Slf4j;
import org.lds.simple.disruptor.sequence.Sequence;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
public class BlockingWaitStrategy implements WaitStrategy {
    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    @Override
    public long consumerWait(Sequence producerSequence, Sequence consumerSequence) {
        while (!allowConsume(producerSequence, consumerSequence)) {
            lock.lock();
            try {
                condition.await();
            } catch (Throwable e) {
                log.error("await fail", e);
            } finally {
                lock.unlock();
            }
        }
        return producerSequence.get();
    }

    @Override
    public void notifyConsumer() {
        lock.lock();
        try {
            condition.signalAll();
        } catch (Throwable e) {
            log.error("notifyConsumer fail", e);
        } finally {
            lock.unlock();
        }
    }


}
